#include "stdafx.h"
#include "WindowsUtility.h"
#include <psapi.h>

namespace RoomFW {

WindowsUtilityLock::WindowsUtilityLock(void)
{
	WindowsUtility::Instance().Lock();
}

WindowsUtilityLock::~WindowsUtilityLock()
{
	WindowsUtility::Instance().Unlock();
}

WindowsUtility::WindowsUtility(void)
{
	::InitializeCriticalSection(&CS_);
	::srand(::GetTickCount());
}

WindowsUtility::~WindowsUtility(void)
{
	::DeleteCriticalSection(&CS_);
}

WindowsUtility& WindowsUtility::Instance()
{
	static WindowsUtility inst;
	return inst;
}

void WindowsUtility::Lock(void)
{
	::EnterCriticalSection(&CS_);
}

void WindowsUtility::Unlock(void)
{
	::LeaveCriticalSection(&CS_);
}

std::string WindowsUtility::LastErrorString(DWORD lastError)
{
    LPVOID lpMsgBuf;

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        lastError,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

	std::string retVal(static_cast<LPTSTR>(lpMsgBuf));
    LocalFree(lpMsgBuf);
	return retVal;
}

void WindowsUtility::ParseCommandLine(std::vector<std::string>& args)
{
	WindowsUtilityLock lock; // for strtok
	args.clear();
	LPSTR cmdLine = ::GetCommandLineA();
	char* cmdLineCopy = new char[strlen(cmdLine) + 1];
	strcpy(cmdLineCopy, cmdLine);
	char* pTok = ::strtok(cmdLineCopy, " ");
	while (0 != pTok)
	{
		args.push_back(pTok);
		pTok = strtok(0, " ");
	}
	delete [] cmdLineCopy;
}

DWORD WindowsUtility::DiffTickCount(DWORD start)
{
	DWORD cur = ::GetTickCount();
	return ((cur < start) ? (UINT_MAX - start + cur) : (cur - start));
}

int WindowsUtility::rand(int min, int max)
{
	return static_cast<int>(
		(static_cast<double>(::rand()) / RAND_MAX) * (max - min) + min);
}

void WindowsUtility::logMemoryUsage()
{
/*	HANDLE hProcess = ::GetCurrentProcess();
    PROCESS_MEMORY_COUNTERS pmc;

	if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
    {
		G_LOG_3_TRACE("SE500 Memory Usage [WS: %.10ld], [Peak WS: %.10ld], [PF Usage: %.10ld]", 
			pmc.WorkingSetSize, pmc.PeakWorkingSetSize, pmc.PagefileUsage);
    }
*/
}

}
